home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / stdg44.exe / lha / BULLWINS.C < prev    next >
C/C++ Source or Header  |  1994-01-10  |  8KB  |  325 lines

  1. /* window.c - this is where it all happens */
  2.  
  3. #include <stdlib.h>
  4. #include "stdg.h"
  5. #include "bullseye.h"
  6.  
  7. #define OFFSCREEN 1         /* 1=use offscreen buffers for every window */
  8.                             /* 0=draw directly to each window */
  9.  
  10. short   wincount = 0;       /* how many windows do we have */
  11.  
  12. enum Shapes {               /* what shape does a window bullseye have */
  13.     OVAL = 0,
  14.     RECTANGLE = 1,
  15.     TRIANGLE = 2
  16. };
  17.  
  18. typedef struct Winfo    Winfo;  /* private bullseye window information */
  19.  
  20. struct Winfo {
  21.     short       shape;
  22.     short       width;
  23.     pixval      fg;
  24.     pixval      bg;
  25.  
  26. #if OFFSCREEN
  27.     bitmap *    b;
  28.     short       changed;
  29. #endif
  30.  
  31. };
  32.  
  33. #define winfo(w)    ((Winfo *) w->data)
  34.  
  35. cursor watch={
  36.     { -9, -8},
  37.     {0x3F, 0xC0, 0x3F, 0xC0, 0x3F, 0xC0, 0x3F, 0xC0,
  38.      0x7F, 0xE0, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF8,
  39.      0xFF, 0xF8, 0xFF, 0xF0, 0xFF, 0xF0, 0x7F, 0xE0,
  40.      0x3F, 0xC0, 0x3F, 0xC0, 0x3F, 0xC0, 0x3F, 0xC0,
  41.     },
  42.     {0x1F, 0x80, 0x1F, 0x80, 0x1F, 0x80, 0x1F, 0x80,
  43.      0x20, 0x40, 0x42, 0x20, 0x42, 0x20, 0x42, 0x30,
  44.      0x4E, 0x30, 0x40, 0x20, 0x40, 0x20, 0x20, 0x40,
  45.      0x1F, 0x80, 0x1F, 0x80, 0x1F, 0x80, 0x1F, 0x80,
  46.     },
  47.     0
  48. };
  49.  
  50. /*
  51.  * The next six functions are the function-call interface to
  52.  * bullseye windows. The above data structures are private to
  53.  * this file, and don't need to be known by anyone else.
  54.  */
  55.  
  56. void set_width(window *w, short width)  /* set line width */
  57. {
  58. #if OFFSCREEN
  59.     winfo(w)->changed = 1;
  60. #endif
  61.     winfo(w)->width = width;
  62.     fill_rect(w->b, w->b->r, WHITE);
  63.     redraw(w);
  64. }
  65.  
  66. void set_fore(window *w, pixval v)  /* set foreground colour */
  67. {
  68. #if OFFSCREEN
  69.     winfo(w)->changed = 1;
  70. #endif
  71.     winfo(w)->fg = v;
  72.     fill_rect(w->b, w->b->r, WHITE);
  73.     redraw(w);
  74. }
  75.  
  76. void set_back(window *w, pixval v)  /* set background colour */
  77. {
  78. #if OFFSCREEN
  79.     winfo(w)->changed = 1;
  80. #endif
  81.     winfo(w)->bg = v;
  82.     fill_rect(w->b, w->b->r, WHITE);
  83.     redraw(w);
  84. }
  85.  
  86. short get_width(window *w)  /* get width of lines in window */
  87. {
  88.     return winfo(w)->width;
  89. }
  90.  
  91. pixval get_fore(window *w)      /* get foreground colour */
  92. {
  93.     return winfo(w)->fg;
  94. }
  95.  
  96. pixval get_back(window *w)      /* get background colour */
  97. {
  98.     return winfo(w)->bg;
  99. }
  100.  
  101. rectangle nice_rect(void)   /* return a nice new rectangle for a window */
  102. {
  103.     long offset;
  104.     rectangle r = rdiag(25,45,100,100);
  105.  
  106.     offset = ((wincount) % 7) * 20;
  107.  
  108.     r = raddp(r,pt(offset,offset));
  109.     wincount++;
  110.  
  111.     return r;
  112. }
  113.  
  114. /*
  115.  * New_bullseye creates a basic bullseye window and returns it.
  116.  * The next three functions customise it to a given shape.
  117.  * The function relies on the nice_rect function to provide a nice
  118.  * location for a bullseye on screen.
  119.  */
  120.  
  121. window *new_bullseye(short shape)   /* make and return a bullseye window */
  122. {
  123.     window *w;
  124.     rectangle r = nice_rect();
  125.  
  126.     w = new_window("Bullseye", r,
  127.         Titlebar | Closebox | Maximize | Resize | Document);
  128.  
  129.     set_winfns(w, &close, &resize, &redraw);
  130.  
  131.     w->data = (void *) malloc(sizeof(Winfo));
  132.     winfo(w)->shape = shape;
  133.     winfo(w)->width = 5;
  134.     winfo(w)->fg = BLACK;
  135.     winfo(w)->bg = WHITE;
  136.  
  137. #if OFFSCREEN
  138.     winfo(w)->b = new_bitmap(r, 0); /* bitmap size & depth of window */
  139.     winfo(w)->changed = 1;  /* remember that this window needs redrawing */
  140. #endif
  141.  
  142.     return w;
  143. }
  144.  
  145.  
  146. void new_oval(void)     /* create new oval shape and show it */
  147. {
  148.     window *w = new_bullseye(OVAL);
  149.  
  150.     set_winname(w, "Oval");
  151.     show_window(w);
  152. }
  153.  
  154. void new_rectangle(void)    /* create new rectangular shape and show it */
  155. {
  156.     window *w = new_bullseye(RECTANGLE);
  157.  
  158.     set_winname(w, "Rectangle");
  159.     show_window(w);
  160. }
  161.  
  162. void new_triangle(void) /* create new triangular shape and show it */
  163. {
  164.     window *w = new_bullseye(TRIANGLE);
  165.  
  166.     set_winname(w, "Triangle");
  167.     show_window(w);
  168. }
  169.  
  170. /*
  171.  * This function is called from main when someone does a mouse click
  172.  * in a bullseye window.
  173.  */
  174.  
  175. void hit_window(window *w)      /* handle mouse down in the window */
  176. {
  177.     fill_rect(w->b, w->b->r, WHITE);
  178.     redraw(w);
  179. }
  180.  
  181. /*
  182.  * Close happens whenever a bullseye window is closed.
  183.  */
  184.  
  185. void close(window *w)       /* close a window */
  186. {
  187. #if OFFSCREEN
  188.     del_bitmap(winfo(w)->b);
  189. #endif
  190.     free(w->data);
  191.     del_window(w);
  192. }
  193.  
  194. /*
  195.  * Paint_oval is the expert that knows how to paint a single oval
  196.  * of a given thickness, colour and size to a bitmap.
  197.  */
  198.  
  199. void paint_oval(bitmap *b, rectangle r, short width, pixval v)
  200. {
  201.     point p0;
  202.     long r1, r2;
  203.     short w;
  204.  
  205.     p0 = divp(addp(r.min,r.max),2);
  206.     r1 = dx(r)/2;
  207.     r2 = dy(r)/2;
  208.     w = width;
  209.  
  210.     while(w > 0) {
  211.         draw_ellipse(b, p0, r1, r2, v);
  212.         r1--;
  213.         r2--;
  214.         w--;
  215.     }
  216. }
  217.  
  218. /*
  219.  * Paint_rectangle uses draw_rect, which uses fill_rect. This makes
  220.  * it faster than the other drawing operations.
  221.  */
  222.  
  223. void paint_rectangle(bitmap *b, rectangle r, short width, pixval v)
  224. {
  225.     short w;
  226.  
  227.     w = width;
  228.  
  229.     if (w > dx(r))
  230.         w = dx(r);
  231.     if (w > dy(r))
  232.         w = dy(r);
  233.  
  234.     draw_rect(b, r, w, v);
  235. }
  236.  
  237. /*
  238.  * Paint_triangle is similar to the THINK C Bullseye triangle shape.
  239.  * It doesn't draw properly inset triangles due to the way the
  240.  * target rectangle is stepped inwards.
  241.  */
  242.  
  243. void paint_triangle(bitmap *b, rectangle r, short width, pixval v)
  244. {
  245.     point p1, p2, p3;
  246.     short w;
  247.  
  248.     p1 = r.min;
  249.     p2 = pt(r.min.x, r.max.y);
  250.     p3 = r.max;
  251.     w = width;
  252.  
  253.     while(w > 0) {
  254.         draw_line(b, p1, p2, v);
  255.         draw_line(b, p2, p3, v);
  256.         draw_line(b, p3, p1, v);
  257.         p1 = addp(p1,pt(1,2));
  258.         p2 = addp(p2,pt(1,-1));
  259.         p3 = addp(p3,pt(-2,-1));
  260.         w--;
  261.     }
  262. }
  263.  
  264. /*
  265.  * Resize is called when a window is resized. Redraw is called afterwards.
  266.  * Here we change the size of the window's offscreen buffer.
  267.  */
  268. void resize(window *w)
  269. {
  270. #if OFFSCREEN
  271.     winfo(w)->changed = 1;
  272.     del_bitmap(winfo(w)->b);
  273.     winfo(w)->b = new_bitmap(w->r, 0);
  274. #endif
  275. }
  276.  
  277. /*
  278.  * Draw does the drawing to a bitmap (could be the window bitmap).
  279.  * It is given some bullseye info and calls the appropriate
  280.  * paint_shape function repeatedly with inward stepping rectangles.
  281.  */
  282.  
  283. void draw(bitmap *b, short width, short shape, pixval fg, pixval bg)
  284. {
  285.     rectangle r = b->r;
  286.  
  287.     set_cursor(&watch);
  288.  
  289.     fill_rect(b, r, bg);                    /* draw background colour */
  290.  
  291.     while(dx(r) > 0 && dy(r) > 0) {         /* step rectangle inwards */
  292.         switch (shape) {
  293.             case OVAL:      paint_oval(b, r, width, fg); break;
  294.             case RECTANGLE: paint_rectangle(b, r, width, fg); break;
  295.             case TRIANGLE:  paint_triangle(b, r, width, fg); break;
  296.         }
  297.         r = insetr(r, width*2);
  298.     }
  299.  
  300.     set_cursor(NULL);
  301. }
  302.  
  303. /*
  304.  * Redraw is called whenever a window needs redrawing.
  305.  * It calls draw if drawing directly to the window, or if the offscreen
  306.  * bitmap needs redrawing.
  307.  * It calls bit_copy to refresh the window from the offscreen bitmap,
  308.  * if an offscreen bitmap exists.
  309.  */
  310.  
  311. void redraw(window *w)
  312. {
  313. #if OFFSCREEN
  314.     if (winfo(w)->changed) {
  315.         draw(winfo(w)->b, winfo(w)->width, winfo(w)->shape,
  316.                     winfo(w)->fg, winfo(w)->bg);
  317.         winfo(w)->changed = 0;
  318.     }
  319.     bit_copy(w->b, pt(0,0), winfo(w)->b, winfo(w)->b->r, S);
  320. #else
  321.     draw(w->b, winfo(w)->width, winfo(w)->shape,
  322.                 winfo(w)->fg, winfo(w)->bg);
  323. #endif
  324. }
  325.